/*
@hehung
2023-2-8
转载请注明出处，版权由@hehung所有
email: 1398660197@qq.com
wechat: hehung95
*/

// 规定蓝牙数据发送的格式为：
// 数据长度(十六进制) + 数据

#include "hal_data.h"
#include "app_buletooth.h"
#include "app_uart.h"
#include "app_hs300x.h"
#include "app_isl29035.h"
#include "app_led.h"

#include <string.h>

#define BT_DEBUG

#ifdef BT_DEBUG
#include <stdio.h>
#define LOG(fmt, ...) 	                printf(fmt, ##__VA_ARGS__)
#else
#define LOG(fmt, ...)
#endif

#define BT_BUFFER_SIZE                  (32U)


// this structure is used to cache the received AT informations
typedef struct
{
    char bt_buf[BT_BUFFER_SIZE];
    uint16_t bt_len;
    uint16_t bt_timeout;
} s_BtCmdType;



static e_BtConnStatusType bt_conn_status = BT_DISCONNECTED;
static s_BtCmdType bt_buff;


// callback function for uart4(used for buletooth with communication)
void uart4_notification(uart_callback_args_t * p_args)
{
	if (p_args->event == UART_EVENT_TX_COMPLETE)
	{
		Bt_TxNotification();
	}
	else if (p_args->event == UART_EVENT_RX_CHAR)
	{
		Bt_RxNotification(p_args->data);
	}
}


// notification for buletooth device connect status
void ext_irq12_notification(external_irq_callback_args_t *p_args)
{
	(void)p_args;
	bsp_io_level_t pin_level;

	if (FSP_SUCCESS ==  R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_08, &pin_level))
    {
        if (BSP_IO_LEVEL_LOW == pin_level)
        {
			// buletooth is connected
			bt_conn_status = BT_DISCONNECTED;
        }
		else
		{
			// buletooth is disconnected
			bt_conn_status = BT_CONNECTED;
		}
    }
}

// initialize buletooth device pins
void Bt_Init(void)
{
	fsp_err_t err;
	bsp_io_level_t pin_level;

	// initialize the uart for communication between buletooth and MCU
	err = R_SCI_UART_Open(&g_uart4_ctrl, &g_uart4_cfg);
    assert(FSP_SUCCESS == err);

	// initialize the P008(Irq12) as interrupt pin, it connnect to the connnect pin in buletooth board
	/* Configure the external interrupt. */
    err = R_ICU_ExternalIrqOpen(&g_external_irq12_ctrl, &g_external_irq12_cfg);
    assert(FSP_SUCCESS == err);
    /* Enable the external interrupt. */
    /* Enable not required when used with ELC or DMAC. */
    err =  R_ICU_ExternalIrqEnable(&g_external_irq12_ctrl);
    assert(FSP_SUCCESS == err);

	// buletooth device Reset pin
	R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_03, BSP_IO_LEVEL_HIGH);
	// buletooth device low power pin - high level for work mode
	R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_02, BSP_IO_LEVEL_HIGH);

	// judge the buletooth connect status
	if (FSP_SUCCESS ==  R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_08, &pin_level))
    {
        if (BSP_IO_LEVEL_LOW == pin_level)
        {
			// buletooth is connected
			bt_conn_status = BT_DISCONNECTED;
        }
		else
		{
			// buletooth is disconnected
			bt_conn_status = BT_CONNECTED;
		}
    }
}

// notification for buletooth device, successfuly sent a charater
void Bt_TxNotification(void)
{

}

// notification for buletooth device, successfully received a character
void Bt_RxNotification(uint32_t rx_data)
{
	// fsp_err_t err;

	if (bt_buff.bt_len < BT_BUFFER_SIZE)
	{
		bt_buff.bt_buf[bt_buff.bt_len] = (char)rx_data;
		bt_buff.bt_len++;
	}
	
	// if (rx_data == '0')
	// {
	// 	Led_LED_2PwmSet(0);
	// 	err = R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t*)"Closed", 6);
	// }
	// else if (rx_data == '1')
	// {
	// 	Led_LED_2PwmSet(1);
	// 	err = R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t*)"Opened", 6);
	// }
	// else
	// {
	// 	err = R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t*)"Unknow", 6);
	// }

}

// return buletooth connect status
e_BtConnStatusType Bt_GetConnectStatus(void)
{
	return bt_conn_status;
}

void Bt_RunningEntry(void)
{
	int command = -1;
	fsp_err_t err = FSP_SUCCESS;

	if (bt_buff.bt_len > 0U)
	{
		// prase the command
		if (strstr(bt_buff.bt_buf, "Lamp"))
		{
			sscanf(bt_buff.bt_buf, "Lamp:%d", &command);
			if ((command >= 0) && (command <= 100))
			{
				// the command is valid
				Led_LampPwmCtrl((uint8_t)command);
				// response the data
				err = R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t*)"Sucess", 6);
				LOG ("BT: Control command is %d", command);
			}
			else
			{
				err = R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t*)"Fail", 4);
				LOG ("BT: Invalid Lamp control command\n");
			}
			if (FSP_SUCCESS != err)
			{
				LOG ("BT: Response command failed\n");
			}
		}

		// clear buffer
		memset(bt_buff.bt_buf, '\0', BT_BUFFER_SIZE);
		bt_buff.bt_len = 0U;
	}

	vTaskDelay(pdMS_TO_TICKS(20));
}

